home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / Telnet 2.6.1d1 4⁄26⁄94 Folder / source / main / Connections.c < prev    next >
Text File  |  1994-04-15  |  20KB  |  635 lines

  1. /****************************************************************
  2. *    NCSA Telnet for the Macintosh                                *
  3. *                                                                *
  4. *    National Center for Supercomputing Applications                *
  5. *    Software Development Group                                    *
  6. *    152 Computing Applications Building                            *
  7. *    605 E. Springfield Ave.                                        *
  8. *    Champaign, IL  61820                                        *
  9. *                                                                *
  10. *    Copyright (c) 1986-1993,                                    *
  11. *    Board of Trustees of the University of Illinois                *
  12. *****************************************************************/
  13.  
  14. #ifdef MPW
  15. #pragma segment 4
  16. #endif
  17.  
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21.  
  22. #include "TelnetHeader.h"
  23.  
  24. #include "telneterrors.h"
  25. #include "DlogUtils.proto.h"
  26.  
  27. #include "wind.h"
  28. #include "event.proto.h"
  29.  
  30. #include "rsmac.proto.h"
  31. #include "vsdata.h"
  32. #include "vskeys.h"
  33. #include "vsinterf.proto.h"
  34. #include "vgtek.proto.h"
  35. #include "tekrgmac.proto.h"
  36. #include "vr.h"
  37. #include "vrrgmac.proto.h" 
  38. #include "network.proto.h"
  39. #include "mydnr.proto.h"
  40. #include "InternalEvents.h"
  41. #include "menuseg.proto.h"
  42. #include "maclook.proto.h"
  43. #include "parse.proto.h"
  44. #include "parse.h"
  45. #include "configure.proto.h"
  46.  
  47. #include "prefs.proto.h"
  48. #include "popup.h"
  49. #include "popup.proto.h"
  50.  
  51. #include "Connections.proto.h"
  52. #include "encrypt.proto.h"
  53. #include "wdefpatch.proto.h"
  54.  
  55. /*    These are all of the variables we need... */
  56.  
  57. extern    Cursor    *theCursors[NUMCURS];        /* all the cursors in a nice bundle */
  58. extern    WindRec    *screens;
  59. extern    short    scrn;
  60. extern    short    nNational;                // Number of user-installed translation tables
  61. extern    MenuHandle    myMenus[];
  62. extern    Boolean    authOK;
  63. extern    Boolean    encryptOK;
  64.  
  65. static    pascal short POCdlogfilter( DialogPtr dptr, EventRecord *evt, short *item);
  66. PROTO_UPP(POCdlogfilter, ModalFilter);
  67.  
  68. void OpenPortSpecial(MenuHandle menuh, short item)
  69. {
  70.     ConnInitParams        **theParams;
  71.     Boolean                success;
  72.     Str255                scratchPstring;
  73.     
  74.     GetItem(menuh, item, scratchPstring);
  75.     
  76.     theParams = NameToConnInitParams(scratchPstring);
  77.     if (theParams == NULL) {
  78.         OutOfMemory(1020);
  79.         return;
  80.         }
  81.         
  82.     success = CreateConnectionFromParams(theParams);
  83. }
  84.  
  85. SIMPLE_UPP(POCdlogfilter, ModalFilter);
  86. pascal short POCdlogfilter( DialogPtr dptr, EventRecord *evt, short *item)
  87. {
  88.     short key;
  89.  
  90.     if (evt->what == keyDown) {
  91.         key = evt->message & charCodeMask;
  92.         if ( ((key == 'F') || (key == 'f')) && (evt->modifiers & cmdKey) ) {
  93.             *item = NCftpcheckbox;
  94.             return(-1);
  95.             }
  96.         if ( ((key == 'A') || (key == 'a')) && (evt->modifiers & cmdKey) ) {
  97.             *item = NCauthenticate;
  98.             return(-1);
  99.             }
  100.         if ( ((key == 'E') || (key == 'e')) && (evt->modifiers & cmdKey) ) {
  101.             *item = NCencrypt;
  102.             return(-1);
  103.             }
  104.         }
  105.     
  106.     return(DLOGwOK_Cancel(dptr, evt, item));
  107. }
  108.  
  109. void    PresentOpenConnectionDialog(void)
  110. {
  111.     ConnInitParams    **InitParams;
  112.     DialogPtr        dptr;
  113.     short            ditem, scratchshort;
  114.     static long        numWind = 1;
  115.     Boolean            success;
  116.     long            scratchlong;
  117.     Str255            scratchPstring;
  118.     Handle            ItemHandle;
  119.     SessionPrefs    **defaultSessHdl;
  120.     MenuHandle        SessPopupHdl;
  121.     Rect            scratchRect;
  122.     Point            SessPopupLoc;
  123.     
  124.     SetCursor(theCursors[normcurs]);
  125.     
  126.     dptr = GetNewMyDialog(NewCnxnDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  127.     if (dptr == NULL) {
  128.         OutOfMemory(1000);
  129.         return;
  130.         }
  131.         
  132.     ditem = 3;
  133.     
  134.     SessPopupHdl = NewMenu(668, "\pSession:");
  135.     if (SessPopupHdl == NULL) {
  136.         OutOfMemory(1000);
  137.         DisposeDialog(dptr);
  138.         return;
  139.         }
  140.         
  141.     UseResFile(TelInfo->SettingsFile);
  142.     AddResMenu(SessPopupHdl, SESSIONPREFS_RESTYPE);
  143.     EnableItem(SessPopupHdl, 0);        // Make sure the entire menu is enabled
  144.     
  145.     GetDItem(dptr, NCsesspopup, &scratchshort, &ItemHandle, &scratchRect);
  146.     SessPopupLoc.h = scratchRect.left;
  147.     SessPopupLoc.v = scratchRect.top;
  148.     SetPort(dptr);
  149.     LocalToGlobal(&SessPopupLoc);
  150.     
  151.     // Get default auth/encrypt settings from default session
  152.     defaultSessHdl = GetDefaultSession();
  153.     HLock((Handle)defaultSessHdl);
  154.  
  155.     BlockMove("\p<Default>", scratchPstring, 15);
  156.     GetHostNameFromSession(scratchPstring);
  157.     SetTEText(dptr, NChostname, scratchPstring);
  158.     SelIText(dptr, NChostname, 0, 32767);
  159.  
  160.     SetCntrl(dptr, NCauthenticate, (**defaultSessHdl).authenticate && authOK);
  161.     SetCntrl(dptr, NCencrypt, (**defaultSessHdl).encrypt && encryptOK);
  162.     DisposeHandle((Handle)defaultSessHdl);
  163.         
  164.     setSessStates(dptr);
  165.  
  166.     while (ditem > NCcancel) {
  167.         ModalDialog(POCdlogfilterUPP, &ditem);
  168.         switch(ditem) {
  169.             case    NCftpcheckbox:
  170.             case    NCauthenticate:
  171.             case    NCencrypt:
  172.                 GetDItem(dptr, ditem, &scratchshort, &ItemHandle, &scratchRect);
  173.                 if ((**(ControlHandle)ItemHandle).contrlHilite == 0) {    // if control not disabled
  174.                     FlipCheckBox(dptr, ditem);
  175.                     setSessStates(dptr);
  176.                 }
  177.                 break;
  178.  
  179.             case    NCsesspopup:
  180.                 InsertMenu(SessPopupHdl, hierMenu);
  181.                 CalcMenuSize(SessPopupHdl);
  182.                 scratchlong = PopUpMenuSelect(SessPopupHdl, SessPopupLoc.v,
  183.                                                 SessPopupLoc.h, 0);
  184.                 DeleteMenu(668);
  185.                 if (scratchlong) {
  186.                     scratchshort = scratchlong & 0xFFFF; //    Apple sez ignore the high word
  187.                     GetItem(SessPopupHdl, scratchshort, scratchPstring);
  188.                     SetTEText(dptr, NChostname, scratchPstring);
  189.                     SelIText(dptr, NChostname, 0, 32767);
  190.                     }
  191.                 break;
  192.                                 
  193.             default:
  194.                 break;
  195.             } // switch
  196.         } // while
  197.     
  198.     DisposeMenu(SessPopupHdl);
  199.     
  200.     if (ditem == NCcancel) {
  201.         DisposeDialog(dptr);
  202.         return;
  203.         }
  204.     
  205.     GetTEText(dptr, NChostname, scratchPstring);
  206.     if (!Length(scratchPstring)) {
  207.         DisposeDialog(dptr);
  208.         return;
  209.         }
  210.         
  211.     InitParams = NameToConnInitParams(scratchPstring);
  212.     if (InitParams == NULL) {
  213.         OutOfMemory(1000);
  214.         DisposeDialog(dptr);
  215.         return;
  216.         }
  217.  
  218.     HLock((Handle)InitParams);
  219.     HLock((Handle)(**InitParams).session);
  220.     GetTEText(dptr, NCwindowname, scratchPstring);
  221.  
  222.     // Copy over the user specified window name.  If blank, CreateConnectionFromParams 
  223.     // will copy the hostname to the windowname and append a number.
  224.     if (Length(scratchPstring)) 
  225.         BlockMove(scratchPstring, (**InitParams).WindowName,
  226.                     (Length(scratchPstring) > 63) ? 64 : (Length(scratchPstring) + 1));
  227.  
  228.     if (GetCntlVal(dptr, NCftpcheckbox)) {
  229.         (**InitParams).ftpstate = 1;
  230.         (**(**InitParams).session).halfdup = 1;        /* BYU */
  231.         }
  232.      if (GetCntlVal(dptr, NCauthenticate))
  233.           (**(**InitParams).session).authenticate = 1;
  234.      else
  235.          (**(**InitParams).session).authenticate = 0;
  236.      if (GetCntlVal(dptr, NCencrypt))
  237.           (**(**InitParams).session).encrypt = 1;
  238.      else
  239.          (**(**InitParams).session).encrypt = 0;
  240.         
  241.     HUnlock((Handle)(**InitParams).session);
  242.     HUnlock((Handle)InitParams);
  243.         
  244.     DisposeDialog(dptr);
  245.     
  246.     success = CreateConnectionFromParams(InitParams);
  247. }
  248.  
  249. // Set states of session checkboxes
  250. void setSessStates (DialogPtr dptr)
  251. {
  252.     if (GetCntlVal(dptr, NCftpcheckbox)  || !authOK)
  253.         Hilite(dptr, NCauthenticate, 255);
  254.     else
  255.         Hilite(dptr, NCauthenticate, 0);
  256.         
  257.     if (GetCntlVal(dptr, NCauthenticate)) {
  258.         Hilite(dptr, NCftpcheckbox, 255);
  259.         Hilite(dptr, NCencrypt, (encryptOK)? 0 : 255);
  260.     } else {
  261.         Hilite(dptr, NCftpcheckbox, 0);
  262.         Hilite(dptr, NCencrypt, 255);
  263.         SetCntrl(dptr, NCencrypt, false);
  264.     }
  265. }
  266.         
  267. Boolean CreateConnectionFromParams( ConnInitParams **Params)
  268. {
  269.     short            scratchshort, fontnumber, offset;
  270.     static short    numWind = 1, stagNum = 1;
  271.     SessionPrefs    *SessPtr;
  272.     TerminalPrefs    *TermPtr;
  273.     short            cur;
  274.     Str32            numPstring;
  275.     Str255            scratchPstring;
  276.     Boolean            scratchBoolean;
  277.     
  278.     SetCursor(theCursors[watchcurs]);                    /* We may be here a bit */
  279.  
  280.     // Check if we have the max number of sessions open
  281.     if (TelInfo->numwindows == MaxSess) return(FALSE);
  282.     
  283.     cur = TelInfo->numwindows;            /* Adjust # of windows and get this window's number */
  284.     TelInfo->numwindows++;
  285.     screens[cur].active = CNXN_NOTINUSE;    // Make sure it is marked as dead (in case we
  286.                                         // abort screen creation after initiating DNR.
  287.                                         // That way CompleteConnectionOpening will know
  288.                                         // we didn't make it.
  289.     HLockHi((Handle)Params);
  290.     HLockHi((Handle)(**Params).terminal);
  291.     HLockHi((Handle)(**Params).session);
  292.     SessPtr = *((**Params).session);
  293.     TermPtr = *((**Params).terminal);
  294.  
  295.     if (Length((**Params).WindowName) == 0) {
  296.         BlockMove((**(**Params).session).hostname, (**Params).WindowName, 
  297.                     Length((**(**Params).session).hostname)+1);
  298.         NumToString(numWind++, numPstring);
  299.         pstrcat((**Params).WindowName, "\p ");
  300.         pstrcat((**Params).WindowName, numPstring);    // tack the number onto the end.
  301.         }
  302.         
  303.     // Get the IP for the host while we set up the connection
  304.     if (DoTheDNR(SessPtr->hostname, cur) != noErr) {
  305.         OutOfMemory(1010);
  306.         DisposeHandle((Handle)(**Params).terminal);
  307.         DisposeHandle((Handle)(**Params).session);
  308.         DisposeHandle((Handle)Params);
  309.         TelInfo->numwindows--;
  310.         updateCursor(1);
  311.         return(FALSE);
  312.         }
  313.         
  314.     DoTheMenuChecks();
  315.     
  316.       screens[cur].authenticate = SessPtr->authenticate && authOK;
  317.       screens[cur].encrypt = SessPtr->encrypt && encryptOK;
  318.  
  319.      if (screens[cur].authenticate || screens[cur].encrypt) {
  320.          if (screens[cur].edata = (CDATA *)NewPtrClear(sizeof(CDATA))) {
  321.              encrypt_init(screens[cur].edata, "Telnet", 0);
  322.              screens[cur].edata->wp = &screens[cur];
  323.          } else {
  324.              screens[cur].encrypt = false;
  325.              screens[cur].authenticate = false;
  326.              screens[cur].edata = NULL;
  327.          }
  328.      } else
  329.          screens[cur].edata = NULL;
  330.      
  331.      for (scratchshort = 0; scratchshort < sizeof(screens[cur].myopts); scratchshort++) {
  332.         screens[cur].myopts[scratchshort] = 0;
  333.         screens[cur].hisopts[scratchshort] = 0;        
  334.     }    
  335.     screens[cur].cannon[0] = '\0';
  336.  
  337.     screens[cur].vtemulation = TermPtr->vtemulation;
  338.     screens[cur].forcesave = SessPtr->forcesave;
  339.     screens[cur].lineAllow = SessPtr->linemode;
  340.     screens[cur].eightbit = TermPtr->eightbit;    // Is this necessary?
  341.     screens[cur].portNum = SessPtr->port;
  342.     screens[cur].emacsmeta = TermPtr->emacsmetakey;
  343.     screens[cur].Xterm = TermPtr->Xtermsequences;
  344.     
  345.     screens[cur].port = -1;                // netxopen will take care of this
  346.  
  347.     screens[cur].lmode = 0;
  348.     for (scratchshort=0; scratchshort<= SLC_ARRAY_SIZE; scratchshort++)
  349.         screens[cur].slc[scratchshort] = -1;
  350.     screens[cur].slc[SLC_IP] = 3;
  351.     screens[cur].slc[SLC_EC] = 127;
  352.     screens[cur].slc[SLC_EL] = 21;
  353.     screens[cur].slc[SLC_EOF] = 4;
  354.     screens[cur].slc[SLC_ABORT] = 3;
  355.     screens[cur].slc[SLC_SUSP] = 26; 
  356.  
  357.     // If the caller has not specified a window location, come up with our own.
  358.     // This function can possibly stagger windows right off the screen.
  359.     if((**Params).WindowLocation.top == 0) {
  360.         offset = ((gApplicationPrefs->StaggerWindows == TRUE) ? 10 : 2) * (stagNum++);
  361.         (**Params).WindowLocation.top = GetMBarHeight() + 10 + offset;
  362.         (**Params).WindowLocation.left  = offset;
  363.         (**Params).WindowLocation.bottom= 30000 + offset;
  364.         (**Params).WindowLocation.right = 30000 + offset;
  365.         }
  366.         
  367.     GetFNum(TermPtr->DisplayFont, &fontnumber);
  368.     
  369.     screens[cur].vs = RSnewwindow( &((**Params).WindowLocation), TermPtr->numbkscroll, TermPtr->vtwidth,
  370.                                     TermPtr->vtheight, (**Params).WindowName, TermPtr->vtwrap,
  371.                                     fontnumber, TermPtr->fontsize, 0,
  372.                                     1,
  373.                                     SessPtr->forcesave);
  374.                                     
  375.     if (screens[cur].vs <0 ) {     /* we have a problem opening up the virtual screen */
  376.         OutOfMemory(1011);
  377.         DisposeHandle((Handle)(**Params).terminal);
  378.         DisposeHandle((Handle)(**Params).session);
  379.         DisposeHandle((Handle)Params);
  380.         TelInfo->numwindows--;
  381.         DoTheMenuChecks();
  382.         updateCursor(1);
  383.         return(FALSE);
  384.         }
  385.  
  386.     screens[cur].wind = RSgetwindow( screens[cur].vs);
  387.     ((WindowPeek)screens[cur].wind)->windowKind = WIN_CNXN;
  388.     
  389.     /*
  390.      * Attach our extra part to display encryption status
  391.      */
  392.     PatchWindowWDEF(screens[cur].wind, &screens[cur]);
  393.  
  394.     screens[cur].arrowmap = TermPtr->emacsarrows;          /* MAT -- save our arrow setting */
  395.     screens[cur].maxscroll= TermPtr->numbkscroll;
  396.     screens[cur].rows = TermPtr->vtheight;                /* BYU 2.4.16 */
  397.     screens[cur].bsdel = SessPtr->bksp;
  398.     screens[cur].crmap = SessPtr->crmap;
  399.     screens[cur].tekclear = SessPtr->tekclear;
  400.     screens[cur].ESscroll= TermPtr->clearsave;
  401.     screens[cur].tektype = SessPtr->tektype;
  402.     screens[cur].wrap = TermPtr->vtwrap;
  403.     screens[cur].pgupdwn = TermPtr->MATmappings;        /* JMB: map pgup/pgdwn/home/end? */
  404.     screens[cur].width= TermPtr->vtwidth;
  405.     screens[cur].TELstop = SessPtr->skey;
  406.     screens[cur].TELgo = SessPtr->qkey;
  407.     screens[cur].TELip = SessPtr->ckey;
  408.     BlockMove((Ptr)SessPtr->hostname, screens[cur].machine, Length(SessPtr->hostname)+1);
  409.     BlockMove(TermPtr->AnswerBackMessage, screens[cur].answerback, 32);
  410.     screens[cur].termstate = VTEKTYPE;
  411.     screens[cur].naws = 0;                                /* NCSA - set default NAWS to zero */
  412.     screens[cur].xfer=0;
  413.     screens[cur].telstate=0;
  414.     screens[cur].timing=0;
  415.     screens[cur].curgraph=-1;                /* No graphics screen */
  416.     screens[cur].ftpport = -1;                /* BYU - No additional FTP port opened yet */
  417.     screens[cur].clientflags = 0;            /* BYU */
  418.     screens[cur].kblen = 0;                /* nothing in the buffer */
  419.     screens[cur].enabled = 1;            /* Gotta be enabled to start with */
  420.     screens[cur].Ittype = 0;
  421.     screens[cur].Isga = 0;                /* I suppress go ahead = no */
  422.     screens[cur].Usga = 0;                /* U suppress go ahead = no */
  423.  
  424.     screens[cur].ftpstate = (**Params).ftpstate;    /* BYU */
  425.     if ((**Params).ftpstate != 0) {        /* BYU */
  426.         screens[cur].termstate=DUMBTYPE;    /* BYU */
  427.         screens[cur].echo=1;                /* BYU - Echo for ftp */
  428.         screens[cur].halfdup = 1;            /* BYU */
  429.     } else {                            /* BYU */
  430.         screens[cur].termstate=VTEKTYPE;    /* BYU */
  431.         screens[cur].echo = 1;
  432.         screens[cur].halfdup = SessPtr->halfdup;    /* BYU */
  433.     }
  434.     
  435.     screens[cur].national = 0;            // Default to no translation.
  436.     // Now see if the desired translation is available, if not use default translation.
  437.     for(scratchshort = 1; scratchshort <= nNational+1; scratchshort++) {
  438.         GetItem(myMenus[National], scratchshort, scratchPstring);
  439.         if (EqualString(SessPtr->TranslationTable, scratchPstring, TRUE, FALSE))
  440.             screens[cur].national = scratchshort-1;
  441.         }
  442.                 
  443.     
  444.     // Set up paste related variables
  445.     screens[cur].incount = 0;
  446.     screens[cur].outcount = 0;
  447.     screens[cur].outptr = NULL;
  448.     screens[cur].outhand = NULL;
  449.     screens[cur].outlen = 0;
  450.     screens[cur].pastemethod = SessPtr->pastemethod;
  451.     screens[cur].pastesize = SessPtr->pasteblocksize;
  452.     
  453.     scratchBoolean = NewRSsetcolor( screens[cur].vs, 0, TermPtr->nfcolor);
  454.     scratchBoolean = NewRSsetcolor( screens[cur].vs, 1, TermPtr->nbcolor);
  455.     scratchBoolean = NewRSsetcolor( screens[cur].vs, 2, TermPtr->bfcolor);
  456.     scratchBoolean = NewRSsetcolor( screens[cur].vs, 3, TermPtr->bbcolor);
  457.  
  458.     addinmenu(cur, (**Params).WindowName, diamondMark);
  459.     screens[cur].active = CNXN_DNRWAIT;            // Signal we are waiting for DNR.
  460.  
  461.     screens[cur].myInitParams = (Handle)Params;
  462.     HUnlock((Handle)(**Params).terminal);
  463.     HUnlock((Handle)(**Params).session);
  464.     // Params handle must stay locked because interrupt level DNR completion routine needs to deref it
  465.  
  466.     VSscrolcontrol( screens[cur].vs, -1, screens[cur].ESscroll);
  467.  
  468.     updateCursor(1);                            /* Done stalling the user */
  469.     return(TRUE);
  470. }
  471.  
  472. void    CompleteConnectionOpening(short dat, ip_addr the_IP, OSErr DNRerror, char *cname)
  473. {
  474.     ConnInitParams    **Params;
  475.     
  476.     if (screens[dat].active != CNXN_DNRWAIT) return;            // Something is wrong.
  477.     
  478.     Params = (ConnInitParams **)screens[dat].myInitParams;
  479.     
  480.     if (DNRerror == noErr) {
  481.         HLockHi((Handle)(**Params).session);
  482.         if (screens[dat].ftpstate != 0)                 /* BYU - ftp client */
  483.             screens[dat].port  = netxopen(the_IP,HFTP,40);    /* BYU 2.4.15 - open to host name */
  484.         else                                             /* BYU */
  485.             screens[dat].port  = netxopen(the_IP,(**(**Params).session).port,40);/* BYU 2.4.15 - open to host name */
  486.         
  487.         // We need the cannonical hostname for Kerberos. Make best guess if
  488.         // DNR did not return a cname.
  489.         if (cname)
  490.             strncpy(screens[dat].cannon, cname, sizeof(screens[dat].cannon));
  491.         else
  492.             strncpy(screens[dat].cannon, (char *)(**(**Params).session).hostname, sizeof(screens[dat].cannon));
  493.         screens[dat].cannon[sizeof(screens[dat].cannon)-1] = '\0';
  494.         
  495.         DisposeHandle((Handle)(**Params).session);
  496.         DisposeHandle((Handle)(**Params).terminal);
  497.         DisposeHandle((Handle)Params);
  498.         
  499.         if (screens[dat].port <0) {                    /* Handle netxopen fail */
  500.             destroyport(dat);
  501.             }
  502.         screens[dat].active = CNXN_OPENING;
  503.         SetMenuMarkToOpeningForAGivenScreen(dat);    /* Change status mark */
  504.         }
  505.     else
  506.         {    // We should report the real DNR error here!
  507.         Str255        errorString, numberString, numberString2, scratchPstring;
  508.         DialogPtr    theDialog;
  509.         short        message, ditem = 3;
  510.         
  511.         HLockHi((Handle)(**Params).session);
  512.         BlockMove((**(**Params).session).hostname, scratchPstring, Length((**(**Params).session).hostname)+1);
  513.  
  514.         if (DNRerror >= -23048 && DNRerror <= -23041) message = DNRerror + 23050;
  515.         else message = 1;
  516.         
  517.         GetIndString(errorString,DNR_MESSAGES_ID, message);
  518.         NumToString((long)0, numberString);
  519.         NumToString((long)DNRerror, numberString2);
  520.         ParamText(scratchPstring, errorString, numberString, numberString2);
  521.         
  522.         theDialog = GetNewMyDialog(DNRErrorDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  523.         ShowWindow(theDialog);
  524.     
  525.         while (ditem > 1)    ModalDialog(DLOGwOKUPP, &ditem);
  526.         DisposeDialog(theDialog);
  527.  
  528.         DisposeHandle((Handle)(**Params).session);
  529.         DisposeHandle((Handle)(**Params).terminal);
  530.         DisposeHandle((Handle)Params);
  531.         destroyport(dat);
  532.         }
  533. }
  534.  
  535. void destroyport(short wind)
  536. {
  537.     Handle    h;
  538.     short    i,
  539.             callNoWindow=0;
  540.  
  541.     SetCursor(theCursors[watchcurs]);        /* We may be here a while */
  542.  
  543.     if (screens[wind].active == CNXN_ISCORPSE) {
  544.         if (screens[wind].curgraph>-1)
  545.             detachGraphics( screens[wind].curgraph);    /* Detach the Tek screen */
  546.         if (screens[wind].outlen>0) {
  547.             screens[wind].outlen=0;                        /* Kill the remaining send*/
  548.             HUnlock( screens[wind].outhand);            /*  buffer */
  549.             HPurge ( screens[wind].outhand);
  550.             }
  551.         }
  552.  
  553.     if (FrontWindow() == screens[wind].wind)
  554.         callNoWindow=1;
  555.  
  556.      if (screens[wind].edata != NULL)
  557.          DisposePtr((Ptr)screens[wind].edata);
  558.  
  559.     /*
  560.      * Get handle to the WDEF patch block, kill the window, and then
  561.      * release the handle.
  562.      */
  563.     h = GetPatchStuffHandle(screens[wind].wind, &screens[wind]);
  564.     RSkillwindow( screens[wind].vs);
  565.     if (h)
  566.         DisposeHandle(h);
  567.  
  568.     screens[wind].active = CNXN_NOTINUSE;
  569.     for (i=wind;i<TelInfo->numwindows-1;i++) {
  570.         screens[i]=screens[i+1];        /* Bump all of the pointers */
  571.         RePatchWindowWDEF(screens[i].wind, &screens[i]);    /* hack hack hack */
  572.          if (screens[i].edata)
  573.              screens[i].edata->wp = &screens[i];
  574.         }
  575.     if (scrn>wind) scrn--;                /* Adjust for deleting a lower #ered screen */
  576.  
  577.     TelInfo->numwindows--;                        /* There are now fewer windows */
  578.     extractmenu( wind);                    /* remove from the menu bar */
  579.  
  580.     DoTheMenuChecks();
  581.  
  582. /* BYU 2.4.11 - the call to "NoWindow()" changes "myfrontwindow", 
  583.                 which is used by "updateCursor()", so we reversed 
  584.                 the order of the following two lines. */
  585.     if (callNoWindow) NoWindow();        /* BYU 2.4.11 - Update cursor stuff if front window */
  586.     updateCursor(1);                    /* BYU 2.4.11 - Done stalling the user */
  587.  
  588. } /* destroyport */
  589.  
  590. void removeport(short n)
  591. {
  592.     Str255        scratchPstring;
  593.     
  594.     SetCursor(theCursors[watchcurs]);                /* We may be here a while */
  595.  
  596.     if (screens[n].curgraph>-1)
  597.         detachGraphics( screens[n].curgraph);        /* Detach the Tek screen */
  598.         
  599.     if (screens[n].outlen>0) {
  600.                 screens[n].outlen=0;                /* Kill the remaining send*/
  601.                 HUnlock( screens[n].outhand);        /*  buffer */
  602.                 HPurge ( screens[n].outhand);
  603.                 }
  604.  
  605.     if (VSiscapturing(screens[n].vs))                /* NCSA: close up the capture */
  606.         CloseCaptureFile(screens[n].vs);            /* NCSA */
  607.  
  608.     if (VSisprinting(screens[n].vs))
  609.         ClosePrintingFile(screens[n].vs);
  610.         
  611.     if (!gApplicationPrefs->WindowsDontGoAway)
  612.         destroyport(n);
  613.     else {
  614.         Str255    temp;
  615.         
  616.         GetWTitle(screens[n].wind, scratchPstring);
  617. #ifdef THINK_C
  618.         sprintf((char *)temp, "(%#s)", scratchPstring);
  619. #else
  620.         PtoCstr(scratchPstring);
  621.         sprintf((char *)temp, "(%s)", scratchPstring);
  622. #endif
  623.         CtoPstr((char *)temp);
  624.         SetWTitle(screens[n].wind, temp);
  625.  
  626.         screens[n].port = 32700;
  627.         screens[n].active = CNXN_ISCORPSE;
  628.         }
  629.  
  630.     updateCursor(1);                            /* Done stalling the user */
  631. } /* removeport */
  632.  
  633.  
  634.  
  635.